home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’93
/
Happy Happy, Joy Joy
/
HappyHappy.c
< prev
next >
Wrap
Text File
|
1993-06-18
|
3KB
|
181 lines
/*
HappyHappy.c
HappyHappy extension. Demonstrates use of PatchWorks trap patching
system to patch DrawString. Uses new GenericPatch class.
by Mouse Herrell & Patrick Beard.
© 1991 Berkeley Systems Inc.
*/
#include <string.h>
#include <Notification.h>
#include <Traps.h>
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include <stddef.h>
#include <Exceptions.h>
#include <Extension.h>
#include <GenericPatch.h>
static int dprintf(const char* format, ...);
//
// DrawStringPatch -- HappyHappy of a head-off patch.
//
class DrawStringPatch : public GenericPatch {
public:
DrawStringPatch();
virtual void Behavior(void);
private:
long itsCallCount;
};
struct DrawStringParameters {
Str255 *theString;
};
typedef struct DrawStringParameters DrawStringParameters;
typedef pascal long (*DrawStringProcPtr) (Point pt);
DrawStringPatch::DrawStringPatch()
{
// initialize instance variables.
itsCallCount = 0;
// install the appropriate patch.
GenericPatch::InitGenericPatch(_DrawString, sizeof(DrawStringParameters));
Install();
}
void DrawStringPatch::Behavior()
{
KeyMap Keys;
int theLen, index;
char *buffer;
int count, Happy;
// announce our presence if control key held down.
//GetKeys(Keys);
//if (Keys[1] & 0x8) {
if (1) { // normally we would check for a message from the Happy Button
DrawStringParameters* params = (DrawStringParameters*)itsFrame->parameters;
// head off the patch and return.
//AbortTrap();
theLen = *(params->theString)[0];
buffer = (char *)(params->theString);
//dprintf("DrawString: params = (%ld), theLen = %x, buffer = %ld",params,theLen,buffer);
count = 0;
Happy = 0;
if (theLen > 3)
for (index=1; index <= theLen; index++)
{
if (isalpha(buffer[index]))
{
if (count == 0)
if (Happy)
buffer[index] = 'J';
else
buffer[index] = 'H';
else if (count == 1)
if (Happy)
buffer[index] = 'o';
else
buffer[index] = 'a';
else if (count == 2)
if (Happy)
buffer[index] = 'o';
else
buffer[index] = 'p';
else
if (Happy)
buffer[index] = 'o';
else
buffer[index] = 'p';
count++;
if ((ispunct(buffer[index+1])) || (isspace(buffer[index+1])))
buffer[index] = 'y';
}
else if (ispunct(buffer[index]))
{
count = 0;
if (Happy)
Happy = 0;
else
Happy = 1;
}
else if (isspace(buffer[index]))
{
count = 0;
if (Happy)
Happy = 0;
else
Happy = 1;
}
}
buffer[theLen] = 'y';
}
}
//
// Install routine. This is where you allocate your patch objects.
// Throw an exception if something fails.
//
void Install()
{
try {
// if extension succeeds, show happy icon.
new DrawStringPatch;
ShowIconFamily(128);
} catch {
// extension failed, show sad icon.
ShowIconFamily(129);
throw(theException);
}
}
//
// Remove routine. This is called when system is shutdown.
// Perhaps this should be removed. Rob thinks it shouldn't even be
// part of the design.
//
void Remove()
{
Patch::RemoveAll();
}
//
// debugging printf.
//
static int dprintf(const char* format, ...)
{
va_list args;
static char str[256];
int count;
va_start(args, format);
count = vsprintf(str, format, args);
va_end(args);
DebugStr(c2pstr(str));
return count;
}